package holdem.workingMemory;

import holdem.*;

/**
 *
 * @author Pai Qi
 * @author qipai0@gmail.com
 * Description:
 * Start Date:
 *
 */

public class PlayEvent {
    private static Integer lastID;

    static {
	lastID = 0;
    }

    //~--- fields & initializers ----------------------------------------------

    public final Card    cardVar;
    public final Integer     id;
    public final Integer intVar;
    public final Integer  playerVar;
    public final Type    type;

    public static enum Type {
	bet, fold, check, phaseChange, showDown, splitPot, dealTableCard,
	moneyGain, dealerChange, revealPlayerHand, gameStart, gameEnd, userQuit,
        playerJoinRequest, playerJoinAccepted, dealHandCard
    }

    //~--- constructors -------------------------------------------------------

    /**
     * The constructor for creating a new event
     * (note that the last 3 attributes are optional
     * depends on the type of event chosen
     * @param type
     * @param intVar
     * @param cardVar
     * @param playerVar
     */
    PlayEvent(
	    Type type, Integer intVar, Card cardVar, Integer playerVar) {

	// see button of this file for a list of combinations of atribute

	this.type      = type;
	this.intVar    = intVar;
	this.cardVar   = cardVar;
	this.playerVar = playerVar;
	this.id        = ++lastID;
	checkIfLegal();
    }

    //~--- methods ------------------------------------------------------------

    /**
     * Check whether two events are identical
     * @param another
     * @return
     */
    @Override
    public boolean equals(Object another) {
	if (another instanceof PlayEvent) {
	    PlayEvent e = (PlayEvent) another;

	    if (type.equals(e.type)
		    && (((intVar == null) && (e.intVar == null))
			|| (intVar.equals(e.intVar))) && (((cardVar == null)
			    && (e.cardVar == null)) || cardVar.equals(
				e.cardVar)) && (((playerVar == null)
				    && (e.playerVar
					== null)) || playerVar.equals(
					    e.playerVar))) {
		return true;
	    }
	}

	return false;
    }

    /**
     * Return a string representation of this PlayEvent
     * @return
     */
    @Override
    public String toString() {
	String vars = "";

	if (intVar != null) {
	    vars += "|"+intVar;
	}

	if (cardVar != null) {
	    vars += "|"+cardVar;
	}

	if (playerVar != null) {
	    vars += "|"+playerVar;
	}

	return "[Event|"+type.toString()+vars+"]";

    }

    /**
     * A method that checks if a card matches with given criteria.
     * Each attribute represents a criteria, null attribute will be ignored
     * @param type
     * @param intVar
     * @param cardVar
     * @param playerVar
     * @return
     */
    public boolean matches(
	    Type type, Integer intVar, Card cardVar, Player playerVar) {
	if ((type != null) && (this.type != type)) {
	    return false;
	}

	if ((intVar != null) && (!this.intVar.equals(intVar))) {
	    return false;
	}

	if ((cardVar != null) && (!this.cardVar.equals(cardVar))) {
	    return false;
	}

	if ((playerVar != null) && (!this.playerVar.equals(playerVar))) {
	    return false;
	}

	return true;
    }

    private void checkIfLegal() {

	// currently only check wrong-placed info
	// does not check illegal null field
	boolean findError = false;

	if (intVar != null) {
	    if ((type != Type.bet) && (type != Type.moneyGain)
		    && (type != Type.phaseChange)) {
		findError = true;
	    }
	}

	if (cardVar != null) {
	    if (type != Type.dealTableCard) {
		findError = true;
	    }
	}

	if (playerVar != null) {
	    if ((type != Type.bet) && (type != Type.fold)
		    && (type != Type.check) && (type != Type.moneyGain)
		    && (type != Type.dealerChange)) {
		findError = true;
	    }
	}

	if (findError) {
	    throw new RuntimeException("found info at the wrong field "
				       +"when trying to create PlayEvent");
	}
    }
}



/*
type of event
inVar value
cardVar value
playerVar value


bet
total bet amount
-
player who's betting


fold
-
-
player who's folding


check
-
-
player who's checking


showDown
-
-
-


splitPot
-
-
-


dealTableCard
-
Card being deal
-


moneyGain
+earned amount
-
the player with money gain


dealerChange
-
-
the new dealer location


phaseChange
current phase # (no table card = phase 0, 3 table cards = phase 1,
 4 table cards = phase 2, 5 table cards = phase 3
-
-

revealPlayerHand
-
Card being revealed (1 card per message)
The player whose card is being revealed
 
 */






